<?php
namespace frontend\modules\Api\controllers;

use common\event\TallyEvent;
use common\models\TallyCategory;
use common\services\ToolService;
use common\services\UploadLocalServices;
use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Yii;
use yii\base\ExitException;
use yii\filters\AccessControl;
use yii\helpers\ArrayHelper;
use yii\base\DynamicModel;
use common\services\TallyCategoryService;

/**
 * Class UserController
 * @package frontend\modules\Api\controllers
 * 分类管理
 */
class CategoryController extends ApiController
{
    /**
     * @return array
     * 引入行为验证 过滤授权
     */
    public function behaviors()
    {
        $config = [
            'access' => [
                'class' => AccessControl::className(),
                'denyCallback' => function($rule, $action){
                    return self::failureResponse(100001, '请先登录!',[]);
                },
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ]
                ]
            ],
        ];
        return ArrayHelper::merge(parent::behaviors(), $config);
    }


    public function actionExport(){
        $tally_id = Yii::$app->getRequest()->get('tally_id');
        if(!$tally_id){
            return self::failureResponse(500,'账户Id不能为空');
        }
        $condition = Yii::$app->getRequest()->get();
        $list = TallyCategoryService::getListTreeByTallyId($tally_id,$condition);
        $retData = [];
        $typeStr = $condition['type'] == 1 ? '收入分类' : '支出分类';
        foreach ($list as $value){
            $retData[] = [
                $value['title'],
                '',
                '',
                $typeStr
            ];
            if(!isset($value['children'])){
                continue;
            }
            foreach ($value['children'] as $kValue){
                $retData[] = [
                    $value['title'],
                    $kValue['title'],
                    '',
                    $typeStr
                ];
                if(!isset($kValue['children'])){
                    continue;
                }
                foreach ($kValue['children'] as $kkValue){
                    $retData[] = [
                        $value['title'],
                        $kValue['title'],
                        $kkValue['title'],
                        $typeStr
                    ];
                }
            }
        }
        $filename = $typeStr.'导出-'.date('YmdHis').'-'.rand(1000,9999).'.csv';
        ToolService::downLoadCsv($filename,[
            '一级分类',
            '二级分类',
            '三级分类',
            '类别（收入或支出）'
        ],$retData);
        $filepath = Yii::$app->request->hostInfo.'/index/down-export?file='.$filename;
        return self::successResponse(['filepath'=>$filepath]);
    }

    /**
     * 重载初始化方案
     */
    public function init()
    {
        parent::init();
        // 注册监听事件
        $this->on(TallyEvent::RECORD_LOG_EVENT,['common\models\Tally','recordLog']);
    }

    /**
     * @throws
     * 分类列表
     */
    public function actionLists()
    {
        $tallyId = Yii::$app->getRequest()->get('tally_id');
        if(!$tallyId){
            return self::failureResponse(500,'账本Id不能为空');
        }
        $this->checkRolePermission($this->_user['id'],$tallyId,'read');
        $condition = Yii::$app->request->get(); // pid type 等参数
        $list = TallyCategoryService::getListTreeByTallyId($tallyId,$condition);
        return self::successResponse($list);
    }


    public function actionListsDatasTree(){
        $tallyId = Yii::$app->getRequest()->get('tally_id');
        if(!$tallyId){
            return self::failureResponse(500,'账本Id不能为空');
        }
        $condition = Yii::$app->request->get(); // pid type 等参数
        $list = TallyCategoryService::getListTreeByTallyId($tallyId,$condition);


    }

    /**
     * @throws
     * 增加分类
     */
    public function actionAdd()
    {
        $form = DynamicModel::validateData([
            'title' => Yii::$app->getRequest()->post('title'),
            'tally_id' => Yii::$app->getRequest()->post('tally_id'),
            'uid'   => $this->_user['id'],
            'type'  => Yii::$app->getRequest()->post('type'),
            'pid'  => Yii::$app->getRequest()->post('pid',0),
            'pic'  => Yii::$app->getRequest()->post('pic',''),
        ],[
            [['title','tally_id','type','pid'], 'required'],
            ['title', 'filter', 'filter' => 'trim'],
            ['title', 'string','min'=> 1,'max'=> 60],
            ['type', 'integer'],
        ]);
        if ($form->hasErrors()) {
            return self::failureResponse(500,current($form->getFirstErrors()));
        }
        // 检查用户操作权限
        $this->checkRolePermission($this->_user['id'],$form->tally_id,'read');
        $result = TallyCategoryService::create(ArrayHelper::toArray($form));
        if($result){
            TallyCategoryService::clearCache($this->_user['id']);
            $this->triggerEvents([
                'tally_id' => $form->tally_id,
                'uid'   => $this->_user['id'],
                'type'  => 1,
                'content' => '添加了分类:'.$form->title
            ]);
            return self::successResponse(['id'=>$result]);
        }else{
            return self::failureResponse(500,'新增失败.'.TallyCategoryService::getError());
        }
    }

    /**
     * @throws
     * 编辑分类
     */
    public function actionEdit()
    {
        $form = DynamicModel::validateData([
            'id'    => Yii::$app->getRequest()->post('id'),
            'title' => Yii::$app->getRequest()->post('title'),
            'pid'  => Yii::$app->getRequest()->post('pid',0),
            'pic'  => Yii::$app->getRequest()->post('pic',''),
        ],[
            [['title','id'], 'required'],
            ['title', 'filter', 'filter' => 'trim'],
            ['title', 'string','min'=> 1,'max'=> 10],
            ['pid', 'integer'],
        ]);
        if ($form->hasErrors()) {
            return self::failureResponse(500,current($form->getFirstErrors()));
        }
        // 检查对账本的操作权限
        $tallyId = Yii::$app->getRequest()->post('tally_id');
        $this->checkRolePermission($this->_user['id'],$tallyId,'write');
        $result = TallyCategoryService::update([
            'id'    => $form->id,
            'tally_id' => $tallyId,
//            'uid'   => $this->_user['id'],
        ],ArrayHelper::toArray($form));
        if($result){
            TallyCategoryService::clearCache($this->_user['id']);
            return self::successResponse();
        }else{
            return self::failureResponse(500,'更新失败.'.TallyCategoryService::getError());
        }
    }

    /**
     * @throws
     * 删除分类
     */
    public function actionDel()
    {
        $id = Yii::$app->getRequest()->post('id');
        if(!$id){
            return self::failureResponse(500,'分类Id不能为空');
        }
        // 检查对账本的操作权限
        $tallyId = Yii::$app->getRequest()->post('tally_id');
        $this->checkRolePermission($this->_user['id'],$tallyId,'write');
        $result = TallyCategoryService::delete([
            'id'    => $id,
            'tally_id' => $tallyId,
//            'uid'   => $this->_user['id']
        ]);
        if($result){
            TallyCategoryService::clearCache($this->_user['id']);
            return self::successResponse();
        }else{
            return self::failureResponse(500,'删除失败.'.TallyCategoryService::getError());
        }
    }


    /**
     * @throws ExitException
     * @throws Exception
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     */
    public function actionImportData(){
        $tally_id = Yii::$app->getRequest()->post('tally_id');
        $type = Yii::$app->getRequest()->post('type');
        if(!$tally_id){
            return self::failureResponse(500,'请选择账本');
        }
        $fileRes = UploadLocalServices::uploadLocalFu();
        if($fileRes['code'] != 0){
            return  self::failureResponse(500,$fileRes['msg']);
        }
        $filePath = $fileRes['data']['path'];
        $spreadsheet = IOFactory::load($filePath);
        $data = $spreadsheet->getSheet(0)->toArray();
        $children = [];
        foreach ($data as $key=>$value){
            if($key < 1){
                continue;
            }
            //如果第一个有
            if($value[1] == null && $value[2] == null && $value[0] != null){
                $children[$value[0]] = [
                    'title'=>$value[0],
                    'tally_id'=>$tally_id,
                    'uid'=>$this->_user['id'],
                    'type'=>$type,
                    'pid'=>0
                ];
            }else if($value[0] != null && $value[1] != null && $value[2] == null){

                if(!isset($children[$value[0]])){
                    $children[$value[0]] = [
                        'title'=>$value[0],
                        'tally_id'=>$tally_id,
                        'uid'=>$this->_user['id'],
                        'type'=>$type,
                        'pid'=>0
                    ];
                }


                if(!isset($children[$value[0]]['children'][$value[1]])){
                    $children[$value[0]]['children'][$value[1]] = [
                        'title'=>$value[1],
                        'tally_id'=>$tally_id,
                        'uid'=>$this->_user['id'],
                        'type'=>$type,
                    ];
                }
            }else if($value[0] != null && $value[1] != null && $value[2] != null){
                if(!isset($children[$value[0]])){
                    $children[$value[0]] = [
                        'title'=>$value[0],
                        'tally_id'=>$tally_id,
                        'uid'=>$this->_user['id'],
                        'type'=>$type,
                        'pid'=>0
                    ];
                }

                if(!isset($children[$value[0]]['children'][$value[1]])){
                    $children[$value[0]]['children'][$value[1]] = [
                        'title'=>$value[1],
                        'tally_id'=>$tally_id,
                        'uid'=>$this->_user['id'],
                        'type'=>$type,
                    ];
                }

                $children[$value[0]]['children'][$value[1]]['children'][] = [
                    'title'=>$value[2],
                    'tally_id'=>$tally_id,
                    'uid'=>$this->_user['id'],
                    'type'=>$type,
                ];
            }else{
                return self::failureResponse(500,'文件第'.($key+1).'行错误，请检查!');
            }
        }

        $connection = Yii::$app->db->beginTransaction();


        try {
            foreach ($children as $value_item){
                //查询一级分类如果没有就新增
                $one_category_info = TallyCategory::find()->where([
                    'tally_id'=>$tally_id,
                    'title'=>$value_item['title'],
                    'type'=>$value_item['type']
                ])->one();
                //不存在
                if(!$one_category_info){
                    $pid = TallyCategoryService::create($value_item);
                }else{
                    $pid = $one_category_info['id'];
                }
                if(isset($value_item['children'])){
                    //二级分类
                    foreach ($value_item['children'] as $value_item_i){
                        $two_category_info = TallyCategory::find()->where([
                            'tally_id'=>$tally_id,
                            'title'=>$value_item_i['title'],
                            'type'=>$value_item_i['type'],
                            'pid'=>$pid
                        ])->one();
                        if(!$two_category_info){
                            $value_item_i['pid'] = $pid;
                            $two_pid = TallyCategoryService::create($value_item_i);
                        }else{
                            $two_pid = $two_category_info['id'];
                        }
                        if(isset($value_item_i['children'])) {
                            foreach ($value_item_i['children'] as  $value_item_i_t){
                                $three_category_info = TallyCategory::find()->where([
                                    'tally_id'=>$tally_id,
                                    'title'=>$value_item_i_t['title'],
                                    'type'=>$value_item_i_t['type'],
                                    'pid'=>$two_pid
                                ])->one();
                                if(!$three_category_info){
                                    $value_item_i_t['pid'] = $two_pid;
                                    TallyCategoryService::create($value_item_i_t);
                                }
                            }
                        }

                    }
                }
            }
            $connection->commit();
            return self::successResponse();
        }catch (\Exception $exception){
            $connection->rollBack();
            return self::failureResponse(500,'导入失败');
        }

    }

}
